package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysDepartmentMapper;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysDepartment;
import com.nineclock.system.service.SysDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SysDepartmentServiceImpl implements SysDepartmentService {

    @Autowired
    private SysDepartmentMapper departmentMapper;

    @Autowired
    private SysCompanyUserMapper companyUserMapper;

    /**
     * 查询当前企业的部门列表
     *
     * @return
     */
    @Override
    public List<SysDepartmentDTO> queryDepartments() {
        //获取当前企业ID (ThreadLocal)
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //获取顶级部门列表
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, companyId);
        wrapper.eq(SysDepartment::getParentId, 0);

        List<SysDepartment> topDepList = departmentMapper.selectList(wrapper);

        if (CollectionUtil.isEmpty(topDepList)) {
            return new ArrayList<SysDepartmentDTO>();
        }

        List<SysDepartmentDTO> departmentDTOS = BeanHelper.copyWithCollection(topDepList, SysDepartmentDTO.class);

        // 递归! 获取这些顶级部门下的子部门列表
        queryChildrenDepartmentList(departmentDTOS);

        return departmentDTOS;
    }

    /**
     * 递归! 获取这些顶级部门下的子部门列表
     *
     * @param departmentDTOList
     */
    private void queryChildrenDepartmentList(List<SysDepartmentDTO> departmentDTOList) {
        departmentDTOList.stream().forEach(sysDepartmentDTO -> {

            LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
            wrapper.eq(SysDepartment::getParentId, sysDepartmentDTO.getId()); //parentId是比那里出来的部门ID

            //获取该部门的子部门
            List<SysDepartment> childrenDepList = departmentMapper.selectList(wrapper);

            //判断 设置递归出口
            if (CollectionUtil.isNotEmpty(childrenDepList)) {
                List<SysDepartmentDTO> childrenDepartmentDTOS = BeanHelper.copyWithCollection(childrenDepList, SysDepartmentDTO.class);

                sysDepartmentDTO.setChildren(childrenDepartmentDTOS);

                //递归调用
                queryChildrenDepartmentList(childrenDepartmentDTOS);
            }
        });
    }

    /**
     * 查询当前企业所有部门ID集合
     *
     * @return
     */
    @Override
    public List<Long> queryDepartmentIds() {

        //获取当前企业ID
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //根据企业ID查询所有部门
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, companyId);
        //获取部门集合
        List<SysDepartment> departments = departmentMapper.selectList(wrapper);

        //遍历部门获取所有ID 存入集合
        List<Long> idsList = departments.stream().map(sysDepartment -> {
            return sysDepartment.getId();
        }).collect(Collectors.toList());

        return idsList;
    }

    /**
     * 根据部门ID 查询直属部门列表 及员工数据
     *
     * @param id            部门ID
     * @param includeMember 0 为包含 ; 1 为 不包含
     * @return
     */
    @Override
    public List<DepartmentOrUserSimpleDTO> querySimleDepartment(Long id, Integer includeMember) {

        List<DepartmentOrUserSimpleDTO> list = new ArrayList<>();

        //组装条件查询员工信息
        if (includeMember == 0) { //包含员工
            LambdaQueryWrapper<SysCompanyUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            userWrapper.eq(SysCompanyUser::getDepartmentId, id);

            List<SysCompanyUser> sysCompanyUsers = companyUserMapper.selectList(userWrapper);

            if (CollectionUtil.isNotEmpty(sysCompanyUsers)) {
                sysCompanyUsers.stream().forEach(sysCompanyUser -> {

                    DepartmentOrUserSimpleDTO simpleUser = new DepartmentOrUserSimpleDTO();
                    simpleUser.setId(sysCompanyUser.getUserId());
                    simpleUser.setName(sysCompanyUser.getUserName());
                    simpleUser.setType(2);

                    list.add(simpleUser);
                });
            }
        }

        //组装查询部门条件
        LambdaQueryWrapper<SysDepartment> depWrapper = new LambdaQueryWrapper<>();
        depWrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        depWrapper.eq(SysDepartment::getParentId, id);

        List<SysDepartment> departments = departmentMapper.selectList(depWrapper);
        if (CollectionUtil.isNotEmpty(departments)) {
            departments.stream().forEach(sysDepartment -> {
                DepartmentOrUserSimpleDTO simpleUser = new DepartmentOrUserSimpleDTO();
                simpleUser.setId(sysDepartment.getId());
                simpleUser.setName(sysDepartment.getName());
                simpleUser.setType(1);

                list.add(simpleUser);
            });
        }

        //组装数据并返回
        return list;
    }

    /**
     * 根据员工id 依次获得部门从低到高级别的部门ID集合
     *
     * @param companyUserId
     * @return
     */
    @Override
    public List<Long> queryDepartmentsByUserId(Long companyUserId) {

        List<Long> depIds = new ArrayList<>();
        //1. 查询员工数据
        SysCompanyUser companyUser = companyUserMapper.selectById(companyUserId);

        //2. 获取员工直属部门ID
        if (companyUser != null) {
            Long departmentId = companyUser.getDepartmentId();
            depIds.add(departmentId);

            //3. 获取当前部门的上级部门ID , 如果不存在, 直接跳出
            while (true) {
                //获取上级部门ID
                SysDepartment department = departmentMapper.selectById(departmentId);
                Long parentId = department.getParentId();

                //如果 parentId=0 顶级部门,跳出
                if (parentId != null && parentId != 0) {
                    depIds.add(parentId);
                    departmentId = parentId;

                } else {
                    break;
                }
            }
        }
        return depIds;
    }
}